use std::{ffi::CString, path::Path, mem::size_of};

use ash::vk::{self, Offset2D};

use crate::{vulkan::{VkContext, vk_utils::{utils_info, utils_pipeline, utils_memory}, vk_struct::{VkSwapchain, VkPipelineGenerator, VkPipeline, VkTexture, VkWriteDescriptorSetGenerator, VkMappedBuffer}, vk_context}, VK_CHECK_UNSAFE, VK_LOGP, VK_LOGD, system::{render::{camera::{PerFrameUniformData, Camera}, render_scene::{RenderEntity, Vertex}}, MAX_FRAMES_IN_FLIGHT}};

use super::Attachment;

// use super::RenderPassTrait;

pub enum MeshPassDescriptorSetLayoutType {
    PerFrame,
    PerMesh,

    SubpassInput,
    Counter
}

pub enum MeshPassTextureType {
    OuterColor,

    InnerColor,
    InnerDepth,

    Counter
}

pub enum MeshPassSubPassType {
    MainPass,
    SubPass,

    Counter
}

pub enum MeshPassPipelineType {
    MeshPipeline,
    InnerPostPipeline,

    Counter
}

pub struct MeshRenderPass {
    pub attachments                 : Vec<Attachment>,
    pub render_pass                 : vk::RenderPass,
    pub framebuffers                : Vec<vk::Framebuffer>,
    pub pipelines                   : Vec<VkPipeline>,
    pub perframe_descriptor_sets    : Vec<vk::DescriptorSet>,
    pub perframe_uniform_buffers    : Vec<VkMappedBuffer<PerFrameUniformData>>,

    pub subpass_descriptor_sets     : Vec<vk::DescriptorSet>
}

impl MeshRenderPass {
    pub fn new(vk_context: &VkContext, vk_swapchain: &VkSwapchain) -> Self {
        let swapchain_extent = vk_swapchain.get_extent();
        let attachments         = Self::setup_attachments(vk_context, &swapchain_extent);

        let render_pass         = Self::setup_vk_render_pass(vk_context, &attachments);
        let framebuffers        = Self::setup_framebuffers(vk_context, &swapchain_extent, &render_pass, &attachments);

        let pipelines            = Self::setup_vk_pipelines(vk_context, &render_pass, &swapchain_extent);
        let subpass_descriptor_sets = Self::setup_subpass_descriptor_set(vk_context, &pipelines, &attachments[MeshPassTextureType::InnerColor as usize].texture);
        let (perframe_uniform_buffers, perframe_descriptor_sets) = Self::setup_perframe_descriptor_set(vk_context, &pipelines);

        Self {
            attachments,
            render_pass,
            framebuffers,
            pipelines,
            perframe_descriptor_sets,
            perframe_uniform_buffers,

            subpass_descriptor_sets
        }
    }

    /// 初始化这个大的RenderPass需要用到的所有Attachment
    /// - 在整理Attachment的时候可以只关注输出部分(因为中间层输入也是另一个SubPass的输出)
    /// - 在定义SubPass的时候，需要使用AttachmentRef来定义，在这个SubPass上，我将这个Attachment视作什么部分
    ///   - Attachment自身只是数据，不知道自己负责什么角色，对于其角色的定义是在每个SubPass的AttachmentRef上
    ///   - RenderPass拥有Attachments，FrameBuffer与Attachments理论上是对应的
    ///   - SubPass拥有AttachmentRef, 其中index指向这个引用的Attachments的位置, layout说明我这个SubPass把这个Attachment看做什么
    ///     - color_attachment_ref就是颜色输出
    ///     - depth_attachment_ref就是深度输出
    ///     - input_attachment_ref是SubPass A需要引用该RenderPass中某个SubPass B输出，对于SubPass B来说这个Attachment可能就隶属于上面两个ref
    ///     - input对应的Layout就是这样描述的layout(input_attachment_index = 0, set = 0, binding = 0)
    ///   - SubPass其他的Layout是这样描述的
    fn setup_attachments(vk_context: &VkContext, extent: &vk::Extent2D) -> Vec<Attachment> {
        let mut attachments = vec![Attachment::default(); MeshPassTextureType::Counter as usize];

        let attachment = &mut attachments[MeshPassTextureType::OuterColor as usize];
        attachment.description   = utils_info::get_attachment_description();
        attachment.description.format           = vk::Format::R32G32B32A32_SFLOAT;
        attachment.description.final_layout     = vk::ImageLayout::GENERAL;
        attachment.texture       = vk_context.create_color_texture(extent.width, extent.height, attachment.description.format, true, false);
        attachment.clear_value   = utils_pipeline::get_clear_color([0.5f32, 0.5f32, 0.5f32, 0.0f32]);

        let attachment = &mut attachments[MeshPassTextureType::InnerColor as usize];
        attachment.description   = utils_info::get_attachment_description();
        attachment.description.format           = vk::Format::R32G32B32A32_SFLOAT;
        attachment.description.final_layout     = vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL;
        attachment.texture       = vk_context.create_color_texture(extent.width, extent.height, attachment.description.format, false, true);
        attachment.clear_value   = utils_pipeline::get_clear_color([0.5f32, 0.5f32, 0.5f32, 0.0f32]);

        let attachment = &mut attachments[MeshPassTextureType::InnerDepth as usize];
        attachment.description   = utils_info::get_attachment_description();
        attachment.description.format           = utils_memory::find_depth_format(vk_context);
        attachment.description.final_layout     = vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
        attachment.texture       = vk_context.create_depth_texture(extent.width, extent.height, attachment.description.format, false);
        attachment.clear_value   = utils_pipeline::get_clear_depth_stencil(1.0, 0);

        attachments
    }

    /// 创建RenderPass
    /// 1. 先将上面创建好的Attachment的描述符拿出来备用
    /// 2. 每个SubPass构建自己需要的AttachmentRef
    /// 3. 创建不同的SubPass之间的同步信息，如果存在依赖关系的话
    fn setup_vk_render_pass(vk_context: &VkContext, attachments: &Vec<Attachment>) -> vk::RenderPass {
        let mut dependencies            = vec![];

        let mut attachment_descriptions = vec![];
        // Setup Attachments
        for attachment in attachments {
            attachment_descriptions.push(attachment.description);
        }

        let mut subpass_descriptions    = vec![utils_info::get_subpass_description(); MeshPassSubPassType::Counter as usize];
        // Setup RenderPass Description
        // {
            // Setup Attachment Ref
            let mut color_attachment_refs   = vec![];
            color_attachment_refs.push( vk::AttachmentReference {attachment: MeshPassTextureType::InnerColor as u32, layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL});

            let depth_attachment_ref = [vk::AttachmentReference {attachment: MeshPassTextureType::InnerDepth as u32, layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL}];

            let mainpass_description = &mut subpass_descriptions[MeshPassSubPassType::MainPass as usize];
            mainpass_description.color_attachment_count         = color_attachment_refs.len() as u32;
            mainpass_description.p_color_attachments            = color_attachment_refs.as_ptr();
            mainpass_description.p_depth_stencil_attachment     = depth_attachment_ref.as_ptr();
        // }

        // {
            // Setup Attachment Ref
            let mut color_attachment_refs   = vec![];
            color_attachment_refs.push(vk::AttachmentReference {attachment: MeshPassTextureType::OuterColor as u32, layout: vk::ImageLayout::GENERAL});

            let mut input_attachment_refs   = vec![];
            input_attachment_refs.push(vk::AttachmentReference {attachment: MeshPassTextureType::InnerColor as u32, layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL});

            let subpass_description = &mut subpass_descriptions[MeshPassSubPassType::SubPass as usize];
            subpass_description.color_attachment_count      = color_attachment_refs.len() as u32;
            subpass_description.p_color_attachments         = color_attachment_refs.as_ptr();
            subpass_description.input_attachment_count      = input_attachment_refs.len() as u32;
            subpass_description.p_input_attachments         = input_attachment_refs.as_ptr();
        // }

        // 这里同步很重要，还得看一会，同步的粒度太多了
        VK_LOGD!("https://zeux.io/data/gdc2020_arm.pdf");
        let outer_dependency = vk::SubpassDependency {
            src_subpass                     : vk::SUBPASS_EXTERNAL,
            dst_subpass                     : MeshPassSubPassType::MainPass as u32,
            src_stage_mask                  : vk::PipelineStageFlags::BOTTOM_OF_PIPE | vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
            dst_stage_mask                  : vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT | vk::PipelineStageFlags::FRAGMENT_SHADER,
            src_access_mask                 : vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
            dst_access_mask                 : vk::AccessFlags::SHADER_READ,// | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
            dependency_flags                : vk::DependencyFlags::BY_REGION,
        };
        dependencies.push(outer_dependency);
        let inner_dependency = vk::SubpassDependency {
            src_subpass                     : MeshPassSubPassType::MainPass as u32,
            dst_subpass                     : MeshPassSubPassType::SubPass as u32,
            src_stage_mask                  : vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT | vk::PipelineStageFlags::FRAGMENT_SHADER,
            dst_stage_mask                  : vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT | vk::PipelineStageFlags::FRAGMENT_SHADER,
            src_access_mask                 : vk::AccessFlags::SHADER_WRITE | vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
            dst_access_mask                 : vk::AccessFlags::SHADER_READ | vk::AccessFlags::COLOR_ATTACHMENT_READ,// | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
            dependency_flags                : vk::DependencyFlags::BY_REGION,
        };
        dependencies.push(inner_dependency);

        let mut render_pass_ci = utils_info::get_render_pass_ci();
        render_pass_ci.subpass_count        = subpass_descriptions.len() as u32;
        render_pass_ci.p_subpasses          = subpass_descriptions.as_ptr();
        render_pass_ci.attachment_count     = attachment_descriptions.len() as u32;
        render_pass_ci.p_attachments        = attachment_descriptions.as_ptr();
        render_pass_ci.dependency_count     = dependencies.len() as u32;
        render_pass_ci.p_dependencies       = dependencies.as_ptr();
        match VK_CHECK_UNSAFE!(vk_context.vk_device.create_render_pass(&render_pass_ci, None)) {
            Some(inner_value)   => inner_value,
            None                => VK_LOGP!("Failed to create_render_pass")
        }
    }

    /// 创建VkPipeline
    /// - Pipeline的概念很重要，以及他和RenderPass的区分
    ///   - Pipeline对应的是一个完整的单次渲染过程，所以Shader信息是绑定在Pipeline上的
    ///   - 既然Pipeline绑定了Shader信息，那么Shader上需要的Input数据理所应当放在Pipeline层
    ///     1. Vertex Input
    ///       - 最重要的一个Input就是顶点信息, 在Pipeline中通过vertex_attribute_descriptions里在对应location设置数据，在shader里面连续的内存[Position, UV, Color]，就可以按location读取到
    ///         - layout(location = 0) in vec3 in_position
    ///       - 这个信息并不是必要的，可以参考PostPipeline里面的技巧，直接渲染三个点，在VertexShader中根据gl_VertexIndex做全屏三角形，理论山Hardware Pipeline在Primitive Assembly之前的顶点操作都可以这样(包括VS、GS、TS等)
    ///     2. Descriptor
    ///       - Descriptor对于OpenGL来说是以命名来描述的，所以第一次理解比较难
    ///       - Descriptor Layout就是一个Descriptor的布局，其实就是手动把Shader中需要的Input给拉了出来
    ///         - 为什么要拉出来，是需要我们手动设置这个地方的Input信息，所以整个Descriptor都是纯的描述，只有WriteDescriptor的时候拿到一个GPU Handler(可以是buffer、image sampler等)绑到DescriptorSet上
    ///         - 在Shader中，我们可以写layout(set = a, binding = b)就是在第a个Set中的第b号binding上对应的Layout
    ///       - Descriptor其实提供了一个更灵活的绑定，对于一个场景中的两个Object，他们的view_proj_mat是相同的，model_mat是不同的，这时候你需要考虑怎么更新这两个矩阵
    ///         - 方法
    ///           1. 将view_proj_mat和model_mat放在一个Descriptor Set上
    ///              - 总共1个DescriptorSet
    ///              - 每帧开始的时候绑定一次
    ///              - 每个物体Draw之前需要WriteDescriptor，这个Write操作在DrawCall间，需要等待
    ///           2. 将view_proj_mat和model_mat放在两个Descriptor Set上，Pipeline管理view_proj_mat，每个Object自己管理的model_mat
    ///              - 总共3个DescriptorSet
    ///              - 每帧开始的时候绑定一次view_proj_mat
    ///              - 每个物体Draw之前绑定一次model_mat，需要WriteDescriptor，这个Write操作不在DrawCall间，可以每帧提取
    ///       - 所有的Descriptor Layout合起来就变成了Pipeline Layout
    ///   - Pipeline可以控制整个硬件渲染管线的参数
    fn setup_vk_pipelines(vk_context: &VkContext, render_pass: &vk::RenderPass, extent: &vk::Extent2D) -> Vec<VkPipeline> {
        VK_LOGD!("这里应该还可以改进，发现Generator模式和初始化模式有点冲突？");
        let mut pipelines = vec![];

        // Generate Main Pipeline
        {
            let mut main_pipeline_generator = VkPipelineGenerator::new(2);
            // Configure pipeline generator
            // Configure shader
            let temp = CString::new("main").unwrap();
            let entry_name = temp.as_ptr();
            main_pipeline_generator.add_shader(vk_context, &Path::new("./vulkan-rt-test/src/shaders/spv/standard.vert.spv"), vk::ShaderStageFlags::VERTEX  , entry_name);
            main_pipeline_generator.add_shader(vk_context, &Path::new("./vulkan-rt-test/src/shaders/spv/standard.frag.spv"), vk::ShaderStageFlags::FRAGMENT, entry_name);
            // Configure Vertex Input
            let vertex_binding_descriptions = [vk::VertexInputBindingDescription {
                binding     : 0,
                stride      : size_of::<Vertex<f32>>() as u32,
                input_rate  : vk::VertexInputRate::VERTEX
            }];
            let vertex_attribute_descriptions = [vk::VertexInputAttributeDescription {
                location    : 0,
                binding     : 0,
                format      : vk::Format::R32G32B32_SFLOAT,
                offset      : 0
            }];
            main_pipeline_generator.state.vertex_input_state.vertex_attribute_description_count     = vertex_attribute_descriptions.len() as u32;
            main_pipeline_generator.state.vertex_input_state.p_vertex_attribute_descriptions        = vertex_attribute_descriptions.as_ptr();
            main_pipeline_generator.state.vertex_input_state.vertex_binding_description_count       = vertex_binding_descriptions.len() as u32;
            main_pipeline_generator.state.vertex_input_state.p_vertex_binding_descriptions          = vertex_binding_descriptions.as_ptr();
            // Configure dynamic state
            let dynamic_states  = vec![vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
            main_pipeline_generator.state.dynamic_state.dynamic_state_count = dynamic_states.len() as u32;
            main_pipeline_generator.state.dynamic_state.p_dynamic_states    = dynamic_states.as_ptr();
            // Configure viewport state
            let viewports       = [utils_pipeline::get_viewport(extent)];
            let scissors        = [utils_pipeline::get_scissor(extent)];
            main_pipeline_generator.state.viewport_state.viewport_count     = viewports.len() as u32;
            main_pipeline_generator.state.viewport_state.p_viewports        = viewports.as_ptr();
            main_pipeline_generator.state.viewport_state.scissor_count      = scissors.len() as u32;
            main_pipeline_generator.state.viewport_state.p_scissors         = scissors.as_ptr();
            // Configure depth stencil state
            main_pipeline_generator.state.depth_stencil_state.depth_write_enable  = vk::TRUE;
            main_pipeline_generator.state.depth_stencil_state.depth_test_enable   = vk::TRUE;
            main_pipeline_generator.state.depth_stencil_state.depth_compare_op    = vk::CompareOp::LESS;
            // Configure color blend state
            let pipeline_color_blend_attachment_state = [utils_info::get_pipeline_color_blend_attachment_state()];
            main_pipeline_generator.state.color_blend_state.attachment_count      = pipeline_color_blend_attachment_state.len() as u32;
            main_pipeline_generator.state.color_blend_state.p_attachments         = pipeline_color_blend_attachment_state.as_ptr();
            // Configure Layout
            main_pipeline_generator.add_set_binding(MeshPassDescriptorSetLayoutType::PerFrame as usize, 0, vk::DescriptorType::UNIFORM_BUFFER, 1, vk::ShaderStageFlags::VERTEX, std::ptr::null());
            main_pipeline_generator.add_set_binding(MeshPassDescriptorSetLayoutType::PerMesh  as usize, 0, vk::DescriptorType::UNIFORM_BUFFER, 1, vk::ShaderStageFlags::VERTEX, std::ptr::null());
            // Do gen
            pipelines.push(main_pipeline_generator.generate(&vk_context, render_pass, MeshPassSubPassType::MainPass as u32));
        }

        // Generatre Sub Pipeline
        {
            let mut sub_pipeline_generator = VkPipelineGenerator::new(1);
            // Configure pipeline generator
            // Configure shader
            let temp = CString::new("main").unwrap();
            let entry_name = temp.as_ptr();
            sub_pipeline_generator.add_shader(vk_context, &Path::new("./vulkan-rt-test/src/shaders/spv/subpass.vert.spv"), vk::ShaderStageFlags::VERTEX  , entry_name);
            sub_pipeline_generator.add_shader(vk_context, &Path::new("./vulkan-rt-test/src/shaders/spv/subpass.frag.spv"), vk::ShaderStageFlags::FRAGMENT, entry_name);
            // Configure dynamic state
            let dynamic_states  = vec![vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
            sub_pipeline_generator.state.dynamic_state.dynamic_state_count = dynamic_states.len() as u32;
            sub_pipeline_generator.state.dynamic_state.p_dynamic_states    = dynamic_states.as_ptr();
            // Configure viewport state
            let viewports       = [utils_pipeline::get_viewport(extent)];
            let scissors        = [utils_pipeline::get_scissor(extent)];
            sub_pipeline_generator.state.viewport_state.viewport_count     = viewports.len() as u32;
            sub_pipeline_generator.state.viewport_state.p_viewports        = viewports.as_ptr();
            sub_pipeline_generator.state.viewport_state.scissor_count      = scissors.len() as u32;
            sub_pipeline_generator.state.viewport_state.p_scissors         = scissors.as_ptr();
            // Configure color blend state
            let pipeline_color_blend_attachment_state = [utils_info::get_pipeline_color_blend_attachment_state()];
            sub_pipeline_generator.state.color_blend_state.attachment_count      = pipeline_color_blend_attachment_state.len() as u32;
            sub_pipeline_generator.state.color_blend_state.p_attachments         = pipeline_color_blend_attachment_state.as_ptr();
            // Configure Layout
            sub_pipeline_generator.add_set_binding(0, 0, vk::DescriptorType::INPUT_ATTACHMENT, 1, vk::ShaderStageFlags::FRAGMENT, std::ptr::null());
            // Do gen
            pipelines.push(sub_pipeline_generator.generate(&vk_context, render_pass, MeshPassSubPassType::SubPass as u32));
        }

        pipelines
    }

    /// 创建Descriptor Set
    /// - 上面Pipeline的地方对Descriptor描述也很详细了
    /// - Descriptor Layout就是单纯的描述，与数据无关，需要去全局的Descriptor Pool分配Descriptor Set才存在数据绑定关系
    /// - 绑定过程也很简单，把要绑定的数据写进WriteDescriptorSet，并且设置好这个数据的binding即可
    fn setup_subpass_descriptor_set(vk_context: &VkContext, pipelines: &Vec<VkPipeline>, inner_texture: &VkTexture) -> Vec<vk::DescriptorSet> {
        let pipeline = &pipelines[MeshPassPipelineType::InnerPostPipeline as usize];

        // 根据输入的Layout创建一定数量的Desceriptor Set
        let mut descriptor_set_ai = utils_info::get_descriptor_set_allocate_info(); 
        descriptor_set_ai.descriptor_pool           = vk_context.vk_descriptor_pool;
        descriptor_set_ai.descriptor_set_count      = 1;
        descriptor_set_ai.p_set_layouts             = [pipeline.descriptor_set_layouts[0]].as_ptr();

        // 将资源的Handler绑定到Descriptor Set上
        // 这里因为Descriptor Set只能一个一个创建
        let mut output_descriptor_sets = vec![];

        for index in 0..MAX_FRAMES_IN_FLIGHT as usize {
            // 创建Set
            let descriptor_sets = match VK_CHECK_UNSAFE!(vk_context.vk_device.allocate_descriptor_sets(&descriptor_set_ai)) {
                Some(inner_value)   => inner_value,
                None                => VK_LOGP!("Failed to allocate_descriptor_sets")
            };
            // 处理对应需要写入的Binding位置
            let mut write_descriptor_generator = VkWriteDescriptorSetGenerator::new();
            let mut descriptor_image_info = inner_texture.description.clone();
            descriptor_image_info.sampler       = vk::Sampler::null();
            descriptor_image_info.image_layout  = vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL;
            write_descriptor_generator.add_image_info(inner_texture, &descriptor_sets[0], 0, &descriptor_image_info, true);

            let write_descriptor_sets = write_descriptor_generator.generate();
            // 向Descriptor Set中写入对应的Handler
            unsafe{ vk_context.vk_device.update_descriptor_sets(write_descriptor_sets, &[]) }

            output_descriptor_sets.push(descriptor_sets[0]);
        }

        output_descriptor_sets
    }

    fn setup_perframe_descriptor_set(vk_context: &VkContext, pipelines: &Vec<VkPipeline>) -> (Vec<VkMappedBuffer<PerFrameUniformData>>, Vec<vk::DescriptorSet>) {
        let pipeline = &pipelines[MeshPassPipelineType::MeshPipeline as usize];

        let perframe_uniform_buffers = vk_context.create_uniform_buffers(MAX_FRAMES_IN_FLIGHT);
        // 根据输入的Layout创建一定数量的Desceriptor Set
        let mut descriptor_set_ai = utils_info::get_descriptor_set_allocate_info(); 
        descriptor_set_ai.descriptor_pool           = vk_context.vk_descriptor_pool;
        descriptor_set_ai.descriptor_set_count      = 1;
        descriptor_set_ai.p_set_layouts             = [pipeline.descriptor_set_layouts[MeshPassDescriptorSetLayoutType::PerFrame as usize]].as_ptr();

        // 将资源的Handler绑定到Descriptor Set上
        // 这里因为Descriptor Set只能一个一个创建
        let mut output_descriptor_sets = vec![];

        for index in 0..MAX_FRAMES_IN_FLIGHT as usize {
            // 创建Set
            let descriptor_sets = match VK_CHECK_UNSAFE!(vk_context.vk_device.allocate_descriptor_sets(&descriptor_set_ai)) {
                Some(inner_value)   => inner_value,
                None                => VK_LOGP!("Failed to allocate_descriptor_sets")
            };
            // 处理对应需要写入的Binding位置
            let mut write_descriptor_generator = VkWriteDescriptorSetGenerator::new();
            let descriptor_buffer_info = vk::DescriptorBufferInfo {
                buffer          : perframe_uniform_buffers[index].buffer.handler,
                offset          : 0,
                range           : size_of::<PerFrameUniformData>() as u64
            };
            write_descriptor_generator.add_buffer_info(&perframe_uniform_buffers[index].buffer.handler, &descriptor_sets[0], 0, size_of::<PerFrameUniformData>() as u64, descriptor_buffer_info);

            let write_descriptor_sets = write_descriptor_generator.generate();
            // 向Descriptor Set中写入对应的Handler
            unsafe{ vk_context.vk_device.update_descriptor_sets(write_descriptor_sets, &[]) }

            output_descriptor_sets.push(descriptor_sets[0]);
        }

        (perframe_uniform_buffers, output_descriptor_sets)
    }

    /// 创建FrameBuffer
    /// 没什么好说的
    fn setup_framebuffers(vk_context: &VkContext, swapchain_extent: &vk::Extent2D, render_pass: &vk::RenderPass, attachments: &Vec<Attachment>) -> Vec<vk::Framebuffer> {
        let mut framebuffers = vec![];

        framebuffers.push(vk_context.create_framebuffer(swapchain_extent.width, swapchain_extent.height, &render_pass, 
            &vec![
                attachments[MeshPassTextureType::OuterColor as usize].texture.description.image_view,
                attachments[MeshPassTextureType::InnerColor as usize].texture.description.image_view, 
                attachments[MeshPassTextureType::InnerDepth as usize].texture.description.image_view,
            ]));
        framebuffers
    }

    pub fn get_output_texture(&self) -> &VkTexture {
        &self.attachments[MeshPassTextureType::OuterColor as usize].texture
    }

    pub fn get_attachment_clear_values(&self) -> Vec<vk::ClearValue> {
        let mut clear_values = vec![];
        for attachment in &self.attachments {
            clear_values.push(attachment.clear_value);
        }
        clear_values
    }

    pub fn on_window_size_changed(&mut self, vk_context: &VkContext, swapchain_extent: &vk::Extent2D) {
        for attachement in &self.attachments {
            vk_context.destory_vk_texture(&attachement.texture);
        }
        vk_context.destory_framebuffers(&self.framebuffers);

        let attachment = &mut self.attachments[MeshPassTextureType::OuterColor as usize];
        attachment.texture       = vk_context.create_color_texture(swapchain_extent.width, swapchain_extent.height, attachment.description.format, true, false);
        let attachment = &mut self.attachments[MeshPassTextureType::InnerColor as usize];
        attachment.texture       = vk_context.create_color_texture(swapchain_extent.width, swapchain_extent.height, attachment.description.format, false, true);
        let attachment = &mut self.attachments[MeshPassTextureType::InnerDepth as usize];
        attachment.texture       = vk_context.create_depth_texture(swapchain_extent.width, swapchain_extent.height, attachment.description.format, false);

        let inner_texture = self.attachments[MeshPassTextureType::InnerColor as usize].texture;
        for index in 0..MAX_FRAMES_IN_FLIGHT as usize {
            // 处理对应需要写入的Binding位置
            let mut write_descriptor_generator = VkWriteDescriptorSetGenerator::new();
            let mut descriptor_image_info = inner_texture.description.clone();
            descriptor_image_info.sampler       = vk::Sampler::null();
            descriptor_image_info.image_layout  = vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL;
            write_descriptor_generator.add_image_info(&inner_texture, &self.subpass_descriptor_sets[index], 0, &descriptor_image_info, true);

            let write_descriptor_sets = write_descriptor_generator.generate();
            // 向Descriptor Set中写入对应的Handler
            unsafe{ vk_context.vk_device.update_descriptor_sets(write_descriptor_sets, &[]) }
        }

        self.framebuffers = Self::setup_framebuffers(vk_context, swapchain_extent, &self.render_pass, &self.attachments);
    }
}